/* 
 * File: itemstablemodel.h
 * Project: QTimeTracker
 * Author: Steve Sindelar, http://stevesindelar.cz
 * Licence: NewBSD licence.
 */
#ifndef ITEMTABLEMODEL_H
#define ITEMTABLEMODEL_H

#include "../QTimeTracker.Core/timespan.h"
#include "../QTimeTracker.Core/xmlpersister.h"
#include "../QTimeTracker.Core/item.h"
#include "abstracttablemodel.h"
#include "tablemodelcolumn.h"
#include <QBrush>

using namespace Core;

namespace Ui
{

	/**
	 * Model of list of \ref Core::Item "Item" instances.
	 * This model is owner of \ref Core::Item "Item" instances, it takes care about memory releasing.
	 */
	class ItemsTableModel : public AbstractTableModel
	{
		Q_OBJECT

	public:
		ItemsTableModel(QList<Item*> data)
		{
			this->_data = data;
			this->addColumn(new NameColumn(this));
			this->addColumn(new LengthColumn(this));
			this->addColumn(new NoteColumn(this));
		}
	    
		int rowCount(const QModelIndex & parent = QModelIndex()) const
		{
			return this->_data.size();        
		}

		/**
		 * Overriden to set up green color for running items.
		 */
		inline QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const
		{
			if (role == Qt::BackgroundRole && this->_data[index.row()]->isRunning())
			{
				return QBrush(Qt::green);
			}
			return AbstractTableModel::data(index, role);
		}

		/**
		 * Returns \ref Core::Item "Item" at specified index.
		 */
		Item* getItem(const QModelIndex &index)
		{     
			return this->_data[index.row()];
		}

		/**
		 * Removes \ref Core::Item "Item" as specified index.
		 * Also releases allocated memory.
		 */
		void removeAt(const QModelIndex &index)
		{
			Item* item = this->_data.at(index.row());
			this->_data.removeAt(index.row());
			delete item;
		}

		/**
		 * Calculates row index of specified \ref Core::Item "Item" pointer.
		 */
		int getItemRow(const Item* item) const
		{
			for(int i=0; i<this->_data.size(); i++)
			{
				if (this->_data[i] == item)
				{
					return i;
				}
			}

			return -1;
		}

		/**
		 * Sets new list of Items for this model.
		 * Old Items will be deleted and memory released.
		 */
		void setData(QList<Item*> data)
		{
			qDeleteAll(this->_data);
			this->_data = data;
			emit this->layoutChanged();
		}

		QList<Item*>& getItems()
		{
			return this->_data;
		}

		/**
		 * Refreshes specified row.
		 */
		void timerTick(int row)
		{
			emit this->dataChanged(this->createIndex(row, 1), this->createIndex(row, 1));
		}

		/**
		 * Refreshes the whole table.
		 */
		void timerTick()
		{
			emit this->dataChanged(this->createIndex(0, 1), this->createIndex(this->rowCount()-1, 1));
		}


	private:
		QList<Item*> _data;

		/** 
		 * @name Columns classes
		 * These classes represent columns in the table. 
		 * They are responsible for providing data of column, header, ...
		 */
		//@{

		class NameColumn : public TableModelColumn
		{
		public:
			NameColumn(ItemsTableModel* model);

			QString getHeader() const;
			QVariant getDataForEditRole(const QModelIndex &index) const;
			QVariant getDataForDisplayRole(const QModelIndex &index) const;
			bool setData(const QModelIndex &index, const QVariant &value) const;
			Qt::ItemFlags getFlags( const QModelIndex & index) const;
		private:
			ItemsTableModel *model;
		};

		class LengthColumn : public TableModelColumn
		{
		public:
			LengthColumn(ItemsTableModel* model);

			QString getHeader() const;
			QVariant getDataForEditRole(const QModelIndex &index) const;
			QVariant getDataForDisplayRole(const QModelIndex &index) const;
			bool setData(const QModelIndex &index, const QVariant &value) const;
			Qt::ItemFlags getFlags( const QModelIndex & index) const;
		private:
			ItemsTableModel *model;
		};

		class NoteColumn : public TableModelColumn
		{
		public:
			NoteColumn(ItemsTableModel* model);

			QString getHeader() const;
			QVariant getDataForEditRole(const QModelIndex &index) const;
			QVariant getDataForDisplayRole(const QModelIndex &index) const;
			bool setData(const QModelIndex &index, const QVariant &value) const;
			Qt::ItemFlags getFlags( const QModelIndex & index) const;
		private:
			ItemsTableModel *model;
		};

		//@}
	};

} // namespace

#endif //ITEMTABLEMODEL_H
